package com.jinxin.platform.cdqzsqacs.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jinxin.platform.cdqzsqacs.bean.gaEntity.Ga_mjjcjlxx;
import com.jinxin.platform.cdqzsqacs.bean.gaEntity.Ga_rlzpxx;
import com.jinxin.platform.cdqzsqacs.service.GaUploadService;
import com.jinxin.platform.cdqzsqacs.task.ResultEntity;
import com.jinxin.platform.cdqzsqacs.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * @author : zhangpeng
 * @date : 2021-05-14 09:52:18
 **/
@Service
@Slf4j
public class GaUploadServiceImpl implements GaUploadService {
    @Value("${cdqzsqacs.appid}")
    private String appid;
    @Value("${cdqzsqacs.secretkey}")
    private String secretkey;
    @Value("${cdqzsqacs.token-url}")
    private String tokenUrl;
    @Value("${cdqzsqacs.gaupload-url}")
    private String gauploadUrl;
    @Value("${cdqzsqacs.zzjgdm}")
    private String zzjgdm;
    @Value("${platform.upload}")
    private String realPath;
    @Autowired
    private RestUtil restUtil;

    @Override
    public String getToken() {
        long time = new Date().getTime();
        int ts = (int) (time / 1000);
        String sign = SHA256Util.getSHA256String("appid" +  this.appid + "appsecret" + this.secretkey + "ts" + ts);

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("appid", this.appid);
        jsonObject.put("appsecret", this.secretkey);
        jsonObject.put("ts", ts);
        jsonObject.put("sign", sign);

        log.info("获取token参数：{}", jsonObject.toString());
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json; charset=utf-8");
        String s = restUtil.restPost(this.tokenUrl, jsonObject.toString(),headers);
        JSONObject resultJson = JSONObject.parseObject(s);
        log.info("获取token接口返回结果：{}", resultJson.get("result").toString());
        String result = resultJson.get("result").toString();
        JSONObject jsonObject1 = JSONObject.parseObject(result);
        log.info("token: {}",jsonObject1.get("token"));
        return (String) jsonObject1.get("token");
    }

    @Override
    public ResultEntity incoming(String name, String jsonStr,boolean hasImg,String imgUrl) {
        String jsonString = jsonStr;
        if(hasImg && !StringUtils.isEmpty(imgUrl)){
            String capBase64 = ImageUtils.getBase64ByImgUrl(imgUrl);
            switch (name){
                case "ga_rlzpxx":
                    List<Ga_rlzpxx> rlzpxxList = new ArrayList<>();
                    List<Ga_rlzpxx> ga_rlzpxxes = JSON.parseArray(jsonStr, Ga_rlzpxx.class);
                    ga_rlzpxxes.forEach(item->{
                        item.setTP(capBase64);
                        rlzpxxList.add(item);
                    });
                    jsonString = JSON.toJSONString(rlzpxxList);
                    break;
                case "ga_mjjcjlxx":
                    List<Ga_mjjcjlxx> mjjcjlxxList = new ArrayList<>();
                    List<Ga_mjjcjlxx> ga_mjjcjlxxes = JSON.parseArray(jsonStr, Ga_mjjcjlxx.class);
                    ga_mjjcjlxxes.forEach(item->{
                        item.setKMRLZP(capBase64);
                        mjjcjlxxList.add(item);
                    });
                    jsonString = JSON.toJSONString(mjjcjlxxList);
                    break;
            }
            log.info("base64长度: " + capBase64.length());
        }
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        try {
            //File file = File.createTempFile(name + "-" + format.format(new Date()) , ".json");
            String baseAddress = System.getProperty("java.io.tmpdir");
            String encryptStr = ThreeDES.encrypt(jsonString);

            String sourceUrl = baseAddress + File.separator + name;
            File file3 = new File(sourceUrl);
            deleteFile(file3);
            File file = new File(sourceUrl + File.separator + name + "-" + format.format(new Date()) + ".json");
            File file1 = new File(sourceUrl);
            if (!file1.exists()) {
                file1.mkdirs();
            } else {
                file1.delete();
            }
            log.info("创建文件:"+ file.getAbsolutePath());
            if (!file.exists()) {
                file.createNewFile();
            }
            log.info("文件是否存在:" + file.exists());
            FileWriter fileWriter = null;
            BufferedWriter bw = null;
            try {
                fileWriter = new FileWriter(file.getAbsoluteFile());
                bw = new BufferedWriter(fileWriter);
                bw.write(encryptStr);
                bw.close();
            } catch (Exception e) {
                log.error("写入文件异常", e);
            } finally {
                if (bw != null) {
                    bw.close();
                }
                if (fileWriter != null) {
                    fileWriter.close();
                }
            }

//            FileUtils.createFile(baseAddress + folder + "/", fileInfo.getFileName() + ".json", jsonString);

            // 将文件夹压缩为ZIP文件 厂商组织机构编号-文件名-时间-6位随机数
            String zipFile = this.zzjgdm + "-" + name + "-" + format.format(new Date()) + "-" + Utils.getRandom6() + ".zip";
            String targetUrl = baseAddress + File.separator + "zipurl";
            File file2 = new File(targetUrl);
            if (!file2.exists()) {
                file2.mkdirs();
            }
            log.info("目标文件路径：{}-----打包文件路径：{}",sourceUrl,targetUrl);
            ZipUtils.zipForIncoming(sourceUrl, targetUrl, zipFile,name);

            String zipBase64 = Base64Utils.encodeBase64File(targetUrl + File.separator + zipFile);
            zipBase64 = zipBase64.replace("\n", "").replace("\r", "");
//            System.out.println(zipBase64);
            String zipMd5 = Md5Encrypt.encryptPassword(zipBase64);

            Map<String, String> params = new HashMap<>();
            String ts = (System.currentTimeMillis() + "").substring(0, 10);
            params.put("zipname", zipFile);
            params.put("zipdata", zipBase64);
            params.put("md5sum", zipMd5);
            params.put("ts", ts);

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("zipname", zipFile);
            jsonObject.put("zipdata", zipBase64);
            jsonObject.put("md5sum", zipMd5);
            jsonObject.put("ts", ts);
            jsonObject.put("sign", getSign(params));

            HttpHeaders headers = new HttpHeaders();
            headers.add("access_token", getToken());
            headers.add("Content-Type", "application/json; charset=utf-8");
            String s = restUtil.restPost(this.gauploadUrl, jsonObject.toString(), headers);
            ResultEntity resultEntity = JSONObject.parseObject(s, ResultEntity.class);
            log.info("返回结果：{}", resultEntity.toString());
            return resultEntity;
        } catch (Exception e) {
            log.error("incoming出现异常", e);
        }
        return null;
    }

    /**
     * 得到签名
     *
     * @param params 参数集合
     * @return
     */
    public String getSign(Map<String, String> params) {
        StringBuilder sb = new StringBuilder();
        //step1：对请求参数排序
        Set<String> keyset = params.keySet();
        TreeSet<String> sortSet = new TreeSet<String>();
        sortSet.addAll(keyset);
        Iterator<String> it = sortSet.iterator();
        //step2：把参数的key value链接起来，得到要加密的字符串
        while (it.hasNext()) {
            String key = it.next();
            String value = params.get(key);
            sb.append(key).append(value);
        }
        //SHA256加密
        String sign = SHA256Util.getSHA256String(sb.toString());
        //log.debug("加密前的字符串【{}】加密后的sign【{}】", sb.toString(), sign);
        return sign;
    }
    static int flag = 1;//用来判断文件是否删除成功

    public void deleteFile(File file){

        //判断文件不为null或文件目录存在
        if (file == null || !file.exists()){
            flag = 0;
            System.out.println("文件删除失败,请检查文件路径是否正确");
            return;
        }
        //取得这个目录下的所有子文件对象
        File[] files = file.listFiles();
        //遍历该目录下的文件对象
        for (File f: files){
            //打印文件名
            String name = file.getName();
            System.out.println(name);
            //判断子目录是否存在子目录,如果是文件则删除
            if (f.isDirectory()){
                deleteFile(f);
            }else {
                f.delete();
            }
        }
        //删除空文件夹  for循环已经把上一层节点的目录清空。
        file.delete();
    }

}
